home *** CD-ROM | disk | FTP | other *** search
/ 17 Bit Software 6: Level 6 / 17 Bit - Level 6 (1998)(Epic Marketing)[!].iso / quartz / q0040.dms / q0040.adf / disass / main.c < prev    next >
C/C++ Source or Header  |  1990-12-05  |  10KB  |  431 lines

  1. /*  (c) 1990 S.Hawtin.
  2.   Permission is granted to copy this file provided
  3.    1) It is not used for commercial gain
  4.    2) This notice is included in all copies
  5.    3) Altered copies are marked as such
  6.  
  7.   No liability is accepted for the contents of the file.
  8.  
  9. */
  10.  
  11. /* A program that will dump out executable code */
  12.  
  13. #include <stdio.h>
  14. #include <stdarg.h>
  15.  
  16. int with_data = TRUE;
  17. int with_code = TRUE;
  18. int with_reloc = TRUE;
  19. int with_code_data = FALSE;
  20. char *data_name = NULL;
  21. FILE *in;
  22.  
  23. #define NAME_LEN 128
  24. char name[NAME_LEN];
  25.  
  26. quit()
  27.    {/* Close down the files and exit */
  28.     fclose(in);
  29.     exit(0);
  30.     }
  31.  
  32. void
  33. my_fread(buff,num,fptr)
  34.     char *buff;
  35.     int  num;
  36.     FILE *fptr;
  37.    {/* Read some bytes into a buffer */
  38.     int i;
  39.  
  40.     for(i=0;i<num;i++)
  41.        {/* The file should be buffered anyway */
  42.         buff[i] = fgetc(fptr);
  43.         if(feof(fptr))
  44.             quit();
  45.         }
  46.     }
  47.  
  48. now_printing = TRUE;
  49.  
  50. void
  51. my_printf(str,args)
  52.     char *str;
  53.    {/* Do a printf, by putting it here we can do things like turn it off
  54.       and duplicate into another file */
  55.     va_list va_args;
  56.  
  57.     va_start(va_args,str);
  58.     if(now_printing)
  59.         vprintf(str,va_args);
  60.     va_end(va_args);
  61.     }
  62.  
  63. /* Because of a new bug in the optimiser these static variables must
  64.    be left outside the function */
  65.  
  66. static char *read_buffer;
  67. static int read_buf_len = 0;
  68.  
  69. char *
  70. read_name(fptr,symb)
  71.     FILE *fptr;
  72.     int symb;
  73.    {/* Read the next name, preceeded by its length */
  74.     long length;
  75.  
  76.     my_fread(&length,sizeof(long),in);
  77.     if(symb)
  78.         length &= 0xffffff;
  79.     if(length*sizeof(long) > read_buf_len-1)
  80.        {if(read_buffer)
  81.             free(read_buffer);
  82.         read_buffer = malloc(length*sizeof(long) + 1);
  83.         if(read_buffer==NULL)
  84.            {my_printf("malloc failed\n");
  85.             exit(20);
  86.             }
  87.         read_buf_len = length*sizeof(long) + 1;
  88.         }
  89.  
  90.     my_fread(read_buffer,length*sizeof(long),in);
  91.     read_buffer[length*sizeof(long)] = '\0';
  92.     return(read_buffer);
  93.     }
  94.  
  95. void
  96. dump_data(in)
  97.     FILE *in;
  98.    {/* Dump out some data */
  99.     unsigned char line[16];
  100.     long length;
  101.     int  line_num,i,old_print;
  102.  
  103.     if(!with_data)
  104.        {
  105.         old_print = now_printing;
  106.         now_printing = FALSE;
  107.         }
  108.  
  109.     my_fread(&length,sizeof(long),in);
  110.     line_num = 0;
  111.     while(line_num < length/4)
  112.        {/* Full line */
  113.         my_fread(line,16,in);
  114.         my_printf("  %05x:",line_num*16);
  115.  
  116.         for(i=0;i<16;i++)
  117.            {
  118.             if(i%4 == 0)
  119.                 my_printf(" ");
  120.             if(i%2 == 0)
  121.                 my_printf(" ");
  122.             my_printf("%02x",line[i]);
  123.             }
  124.         my_printf("  ");
  125.         for(i=0;i<16;i++)
  126.            {
  127.             my_printf("%c",(line[i]>=0x20 && line[i]<0x80)?line[i]:'.');
  128.             }
  129.         my_printf("\n");
  130.         line_num++;
  131.         }
  132.  
  133.     /* Final line */
  134.     length -= line_num*4;
  135.     if(0 != length)
  136.        {/* We have a partial line */
  137.         my_fread(line,length*4,in);
  138.         my_printf("  %05x:",line_num*16);
  139.  
  140.         for(i=0;i<16;i++)
  141.            {
  142.             if(i%4 == 0)
  143.                 my_printf(" ");
  144.             if(i%2 == 0)
  145.                 my_printf(" ");
  146.             if(length*4<=i)
  147.                 my_printf("  ");
  148.               else
  149.                 my_printf("%02x",line[i]);
  150.             }
  151.         my_printf("  ");
  152.         for(i=0;i<length*4;i++)
  153.            {
  154.             my_printf("%c",(line[i]>=0x20 && line[i]<0x80)?line[i]:'.');
  155.             }
  156.         my_printf("\n");
  157.         }
  158.     if(!with_data)
  159.        {
  160.         now_printing = old_print;
  161.         }
  162.     }
  163.  
  164. void
  165. dump_code(in)
  166.     FILE *in;
  167.    {/* Dump executable code */
  168.     int old_print;
  169.  
  170.     if (!with_code)
  171.        {old_print = now_printing;
  172.         now_printing = FALSE;
  173.         }
  174.     if(with_code_data)
  175.         dump_data(in);
  176.       else
  177.        {/* Dump the code as real code, not done yet */
  178.         long length;
  179.  
  180.         my_fread(&length,sizeof(long),in);
  181.         disass(length,in);
  182.         }
  183.     if(!with_code)
  184.        {
  185.         now_printing = old_print;
  186.         }
  187.     }
  188.  
  189. void
  190. dump_reloc(num,in)
  191.     long num;
  192.     FILE *in;
  193.    {/* Dump relocations on multiple lines */
  194.     int i;
  195.     long val;
  196.     int old_print;
  197.  
  198.     i=0;
  199.     if(num>4)
  200.        {
  201.         if (!with_reloc)
  202.            {old_print = now_printing;
  203.             now_printing = FALSE;
  204.             }
  205.         while(num>0)
  206.           {if (i%5 == 0)
  207.                my_printf("\n    ");
  208.            my_fread(&val,sizeof(long),in);
  209.            my_printf(" %08x",val);
  210.            --num;
  211.            ++i;
  212.            }
  213.         if (!with_reloc)
  214.            {
  215.             now_printing = old_print;
  216.             }
  217.         }
  218.       else
  219.         while(num>0)
  220.            {my_fread(&val,sizeof(long),in);
  221.             my_printf(" %08x",val);
  222.             --num;
  223.             }
  224.     my_printf("\n");
  225.     }
  226.  
  227. void
  228. dump_reloc32(in)
  229.     FILE *in;
  230.    {/* Inter hunk relocation information */
  231.     long num,val;
  232.  
  233.     my_fread(&num,sizeof(long),in);
  234.     while(num!=0)
  235.        {/* Dump this relocation */
  236.         my_fread(&val,sizeof(long),in);
  237.         my_printf("  Hunk %2ld  @  ",val);
  238.         dump_reloc(num,in);
  239.         my_fread(&num,sizeof(long),in);
  240.         }
  241.     }
  242.  
  243. void
  244. dump_ext(in)
  245.     FILE *in;
  246.    {/* Dump external symbol table */
  247.     int next;
  248.     long num;
  249.  
  250.     next = getc(in);
  251.     ungetc(next,in);
  252.     while(next!=0)
  253.        {/* Dump out this symbol */
  254.         my_printf("  \"%s\" ",read_name(in,TRUE));
  255.         my_fread(&num,sizeof(long),in);
  256.         switch(next)
  257.            {
  258.             case 0x02:
  259.                 my_printf("Abs Val ");
  260.             case 0x01:
  261.                 my_printf(" =  %08x\n",num);
  262.                 break;
  263.             case 0x83:
  264.                 my_printf(" 16 bit ");
  265.             case 0x81:
  266.                 my_printf(" @ ");
  267.                 dump_reloc(num,in);
  268.                 break;
  269.             default:
  270.                 my_printf("### ERROR ###  Ext code of %02x\n",next);
  271.             }
  272.             
  273.         next = getc(in);
  274.         ungetc(next,in);
  275.         }
  276.     my_fread(&num,sizeof(long),in);
  277.     if(num!=0)
  278.         my_printf("### ERROR ###  End of Ext %08x\n",num);
  279.     }
  280.  
  281. void
  282. dump_symbol(in)
  283.     FILE *in;
  284.    {/* Dump symbol entries */
  285.     char *name;
  286.     long val;
  287.  
  288.     do {
  289.         name = read_name(in,TRUE);
  290.         if(*name)
  291.            {my_fread(&val,sizeof(long),in);
  292.             my_printf("  \"%s\"  =  %08x\n",name,val);
  293.             }
  294.         } while(*name);
  295.     }
  296.  
  297. void
  298. dump_header(in)
  299.     FILE *in;
  300.    {/* Dump the hunk header */
  301.     long val1,val2,val3,val4;
  302.  
  303.     my_fread(&val1,sizeof(long),in);
  304.     my_fread(&val2,sizeof(long),in);
  305.     my_fread(&val3,sizeof(long),in);
  306.     my_fread(&val4,sizeof(long),in);
  307.     /* The first seems to always be 0 */
  308.     my_printf("  %ld %ld %ld %ld   ",val1,val2,val3,val4);
  309.     dump_reloc(val2,in);
  310.     }
  311.  
  312. void
  313. doopts(argc,argv)
  314.     int argc;
  315.     char **argv;
  316.    {/* Get the command line options */
  317.     int i;
  318.  
  319.     for(i=1;i<argc;i++)
  320.        {if(argv[i][0] == '-')
  321.            {
  322.             switch(argv[i][1])
  323.                {
  324.                 case 'h': case 'H':
  325.                     /* Ignore the actual data */
  326.                     with_data = FALSE;
  327.                     with_code = FALSE;
  328.                     with_reloc = FALSE;
  329.                     break;
  330.                 case 'L': case 'l':
  331.                     with_code_data = TRUE;
  332.                     break;
  333.                 default:
  334.                     /* Tell the user the real set of options */
  335.                     goto out_options;
  336.                 }
  337.             }
  338.           else if(data_name==NULL)
  339.            {/* Data file name */
  340.             data_name = argv[i];
  341.             }
  342.           else
  343.            {
  344. out_options:
  345.             my_printf("Options are\n\n");
  346.             my_printf("    -h\n");
  347.             my_printf("    -l\n");
  348.             my_printf("    <objectfile>\n");
  349.             exit(20);
  350.             }
  351.         }
  352.     }
  353.  
  354. void
  355. main(argc,argv)
  356.     int argc;
  357.     char **argv;
  358.    {/* dump out what the contents are */
  359.     int count;
  360.     long len;
  361.  
  362.     doopts(argc,argv);
  363.  
  364.     if(data_name==NULL)
  365.        {printf("Need file name to read\n");
  366.         exit(20);
  367.         }
  368.  
  369.     in = fopen(data_name,"r");
  370.     if(in==NULL)
  371.        {printf("Cannot open \"%s\"\n",data_name);
  372.         exit(20);
  373.         }
  374.  
  375.     /* So we can now get down to the serious buisness of scanning the 
  376.        data file */
  377.  
  378.     count = 0;
  379.     while(TRUE)
  380.        {/* Keep scanning until we have an end of file or we find 
  381.            a final marker */
  382.         long flag;
  383.  
  384.         my_fread(&flag,4,in);
  385.         switch(flag)
  386.            {case 0x3e7:
  387.                 my_printf("Hunk PU Name \"%s\"\n",read_name(in,FALSE));
  388.                 break;
  389.             case 0x3e8:
  390.                 my_printf("Hunk Name \"%s\"\n",read_name(in,FALSE));
  391.                 break;
  392.             case 0x3e9:
  393.                 my_printf("Hunk Code Public\n");
  394.                 dump_code(in);
  395.                 break;
  396.             case 0x3ea:
  397.                 my_printf("Hunk Data Public\n");
  398.                 dump_data(in);
  399.                 break;
  400.             case 0x3eb:
  401.                 my_fread(&len,sizeof(long),in);
  402.                 my_printf("Hunk BSS Public %x\n",len*4);
  403.                 break;
  404.             case 0x3ec:
  405.                 my_printf("Hunk Reloc 32\n");
  406.                 dump_reloc32(in);
  407.                 break;
  408.             case 0x3ef:
  409.                 my_printf("Hunk Ext\n");
  410.                 dump_ext(in);
  411.                 break;
  412.             case 0x3f0:
  413.                 my_printf("Hunk Symbol\n");
  414.                 dump_symbol(in);
  415.                 break;
  416.             case 0x3f2:
  417.                 my_printf("Hunk End\n");
  418.                 break;
  419.             case 0x3f3:
  420.                 my_printf("Hunk Header\n");
  421.                 dump_header(in);
  422.                 break;
  423.             default:
  424.                 count++;
  425.                 my_printf("%08x ",flag);
  426.                 if((count%4) == 0)
  427.                     my_printf("\n");
  428.             }
  429.         }
  430.     }
  431.